Passing Data Between Activities Using Intents in Android
Course: Android App Development
Topic: Passing Data Between Activities Using Intents
Course Link: Android App Development Training
Demo Link: Register for a Free Course Demo
Official Website: JustAcademy
1. Introduction to Passing Data Between Activities
In Android application development, an Activity represents a screen through which users interact with an application. Most applications contain multiple activities to perform different tasks, such as logging in, viewing a profile, displaying product details, or submitting a form.
When users navigate from one activity to another, the application often needs to transfer information between those screens. For example, a login screen may pass a username to a dashboard, or a product list may send a product ID to a product details screen.
Android provides Intents to support communication between activities. An Intent can carry additional information through a collection of key-value pairs called extras.
Example Scenario
Consider an application with two activities:
- MainActivity: Accepts the user's name through an input field.
- SecondActivity: Receives the name and displays a personalized welcome message.
The first activity places the name inside an Intent, starts the second activity, and the second activity retrieves the value.
2. Learning Objectives
After studying this topic, learners will be able to:
- Understand how Android Intents transfer information between activities.
- Differentiate between explicit and implicit Intents.
- Pass data using Intent extras and key-value pairs.
- Retrieve strings, integers, Boolean values, and other supported data types.
- Transfer multiple values between activities.
- Pass objects using Parcelable or Serializable when appropriate.
- Handle missing values and avoid common data-transfer errors.
- Implement a complete example using Kotlin.
3. What Is an Intent?
An Intent is a messaging object used to request an action from another Android application component. It can be used to start an Activity, start a Service, or deliver a broadcast, depending on the type of Intent and the API involved.
When passing data between activities, the Intent identifies the destination activity and optionally contains extra information for that activity.
Basic Syntax in Kotlin
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("username", "Rahul")
startActivity(intent)
In this example:
Intent(this, SecondActivity::class.java) creates an explicit Intent targeting SecondActivity.
putExtra() adds data to the Intent.
"username" is the key used to identify the value.
"Rahul" is the value being transferred.
startActivity(intent) opens the destination activity.
4. Types of Intents
4.1 Explicit Intent
An explicit Intent specifies the exact Android component that should handle the request. It is commonly used to navigate between activities within the same application.
val intent = Intent(this, ProfileActivity::class.java)
intent.putExtra("userId", 101)
startActivity(intent)
Use cases:
- Opening a profile screen from a dashboard.
- Navigating from a product list to a product details screen.
- Moving from a login screen to a home screen.
4.2 Implicit Intent
An implicit Intent describes an action without specifying one exact destination component. Android determines which application component can handle the action.
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.example.com")
startActivity(intent)
This example requests that Android open a web address using a compatible application. Implicit Intents are not generally the preferred method for transferring private application data between two known activities.
5. Understanding Intent Extras
Intent extras are additional pieces of information attached to an Intent. They are stored in a Bundle-like key-value structure, allowing the destination activity to retrieve values using their keys.
Common Methods
| Method |
Purpose |
Example |
putExtra() |
Adds a value to an Intent. |
putExtra("name", "Amit") |
getStringExtra() |
Retrieves a String value. |
getStringExtra("name") |
getIntExtra() |
Retrieves an integer with a default value. |
getIntExtra("age", 0) |
getBooleanExtra() |
Retrieves a Boolean with a default value. |
getBooleanExtra("active", false) |
getLongExtra() |
Retrieves a Long value with a default value. |
getLongExtra("id", -1L) |
getDoubleExtra() |
Retrieves a Double value with a default value. |
getDoubleExtra("price", 0.0) |
getExtras() |
Accesses the Bundle containing extras. |
intent.extras |
Important: The key used to retrieve a value must match the key used when adding it. The value's data type must also match the retrieval method.
6. Creating a Simple Android Project
Before implementing data transfer, create an Android project in Android Studio.
Step 1: Create the Project
- Open Android Studio.
- Select New Project.
- Choose an appropriate template, such as Empty Views Activity, if you are using XML layouts.
- Choose Kotlin as the programming language.
- Create the project and allow Gradle synchronization to complete.
Step 2: Create the Activities
Create two activities:
MainActivity — sends data.
SecondActivity — receives and displays data.
For a standard activity-based example, ensure that both activities are declared in the application manifest. Android Studio normally registers activities created through its activity templates automatically.
7. Passing a String Between Activities
This is the simplest and most common form of Intent-based data transfer.
7.1 MainActivity.kt — Sending Data
package com.example.intentdemo
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val nameInput = findViewById<EditText>(R.id.nameInput)
val nextButton = findViewById<Button>(R.id.nextButton)
nextButton.setOnClickListener {
val name = nameInput.text.toString().trim()
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("username", name)
startActivity(intent)
}
}
}
7.2 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="24dp">
<EditText
android:id="@+id/nameInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your name"
android:inputType="textPersonName" />
<Button
android:id="@+id/nextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Continue" />
</LinearLayout>
7.3 SecondActivity.kt — Receiving Data
package com.example.intentdemo
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
val welcomeText = findViewById<TextView>(R.id.welcomeText)
val username = intent.getStringExtra("username")
.orEmpty()
welcomeText.text = "Welcome, $username!"
}
}
7.4 activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:id="@+id/welcomeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome!"
android:textSize="24sp" />
</LinearLayout>
Expected Output
- The first screen displays a text field and a Continue button.
- The user enters
Rahul.
- After tapping Continue, SecondActivity opens.
- The second screen displays
Welcome, Rahul!.
Note: Replace com.example.intentdemo with your actual package name if necessary.
8. Passing Multiple Values Between Activities
An Intent can carry multiple extras. This is useful when a destination screen needs several related values, such as a user's name, age, email address, and account status.
Sending Multiple Values
val intent = Intent(this, ProfileActivity::class.java)
intent.putExtra("username", "Priya")
intent.putExtra("age", 25)
intent.putExtra("email", "[email protected]")
intent.putExtra("isActive", true)
startActivity(intent)
Receiving Multiple Values
val username = intent.getStringExtra("username").orEmpty()
val age = intent.getIntExtra("age", 0)
val email = intent.getStringExtra("email").orEmpty()
val isActive = intent.getBooleanExtra("isActive", false)
val message = """
Name: $username
Age: $age
Email: $email
Active: $isActive
""".trimIndent()
The receiving activity can display these values in TextViews or use them to populate a profile interface.
9. Passing Data Using a Bundle
A Bundle is a container for key-value pairs. It can be attached to an Intent through putExtras(). This approach can make the transfer of a group of related values easier to organize.
Sending a Bundle
val bundle = Bundle().apply {
putString("name", "Aarav")
putInt("age", 22)
putBoolean("verified", true)
}
val intent = Intent(this, ProfileActivity::class.java)
intent.putExtras(bundle)
startActivity(intent)
Receiving a Bundle
val bundle = intent.extras
val name = bundle?.getString("name").orEmpty()
val age = bundle?.getInt("age", 0) ?: 0
val verified = bundle?.getBoolean("verified", false) ?: false
Use a Bundle when grouping related extras improves readability. For a few simple values, adding extras directly to the Intent is equally valid.
10. Passing Arrays and Lists
Intent extras also support certain arrays and collection types. For example, a list of strings can be passed using an ArrayList.
Sending a List of Strings
val subjects = arrayListOf(
"Kotlin",
"Android",
"SQLite"
)
val intent = Intent(this, SubjectsActivity::class.java)
intent.putStringArrayListExtra("subjects", subjects)
startActivity(intent)
Receiving the List
val subjects = intent
.getStringArrayListExtra("subjects")
.orEmpty()
subjects.forEach { subject ->
println(subject)
}
For arrays, lists, and larger payloads, check the relevant Android API and type constraints. Avoid transferring unnecessarily large collections through Intents.
11. Passing Custom Objects Between Activities
Sometimes an application needs to pass a structured object instead of individual primitive values. For example, a product object might contain a product ID, title, and price.
Android supports transferring suitable objects through mechanisms such as Parcelable and Serializable. Parcelable is generally preferred for Android-specific inter-component data transfer because it is designed for Android's parceling system.
11.1 Define a Parcelable Data Class
With Kotlin and the Parcelize plugin enabled, a simple data class can be declared as follows:
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class Product(
val id: Int,
val name: String,
val price: Double
) : Parcelable
To use @Parcelize, ensure the Kotlin Parcelize plugin is enabled in your module's Gradle configuration.
11.2 Send the Object
val product = Product(
id = 101,
name = "Wireless Headphones",
price = 1999.0
)
val intent = Intent(this, ProductDetailsActivity::class.java)
intent.putExtra("product", product)
startActivity(intent)
11.3 Receive the Object
val product: Product? =
if (android.os.Build.VERSION.SDK_INT >= 33) {
intent.getParcelableExtra(
"product",
Product::class.java
)
} else {
@Suppress("DEPRECATION")
intent.getParcelableExtra("product")
}
product?.let {
println("Product: ${it.name}")
println("Price: ${it.price}")
}
The typed getParcelableExtra() overload is available from Android API level 33. The example uses a version check to support older Android versions.
Parcelable vs Serializable
| Feature |
Parcelable |
Serializable |
| Purpose |
Android-oriented data transfer. |
Java object serialization. |
| Implementation |
Uses Android parceling mechanisms; Kotlin Parcelize can generate boilerplate. |
Uses the Java serialization mechanism. |
| Typical use |
Passing suitable objects between Android components. |
Cases where Java serialization is specifically useful. |
| Recommendation |
Commonly preferred for Android Intent extras. |
Use when its serialization behavior suits the requirement. |
12. Passing Data Back to a Previous Activity
Sometimes the second activity needs to return a result to the first activity. For example, a user may select a city on one screen and return the selected city to the previous screen.
For modern Android development, the Activity Result API is the recommended approach for launching an activity and receiving its result.
12.1 Register an Activity Result Launcher
private val cityLauncher =
registerForActivityResult(
androidx.activity.result.contract.ActivityResultContracts
.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK) {
val city = result.data
?.getStringExtra("selectedCity")
.orEmpty()
// Update a TextView or another UI element.
}
}
Register the launcher as a property of the Activity before the Activity reaches the STARTED state. The exact UI update depends on your layout.
12.2 Launch the Second Activity
val intent = Intent(this, CitySelectionActivity::class.java)
cityLauncher.launch(intent)
12.3 Return the Selected Value
val resultIntent = Intent()
resultIntent.putExtra("selectedCity", "Mumbai")
setResult(RESULT_OK, resultIntent)
finish()
The second activity places the selected city in the result Intent, sets the result code, and finishes. The launcher callback in the first activity receives the result.
13. Data Transfer Through the Android Activity Lifecycle
Intent extras are normally read when the destination activity is created. However, Android can recreate activities due to configuration changes, process recreation, or other lifecycle events.
Developers should distinguish between transferring initial navigation data and preserving changing screen state.
- Use Intent extras to provide the information required to open a destination screen.
- Use
onCreate() to initialize the screen and read its launch data.
- Use saved instance state or a suitable state holder to preserve transient UI state when needed.
- Use a ViewModel to manage screen-related data across configuration changes.
- Use persistent storage or a repository for important application data that must survive process death.
An Intent is a message for launching or communicating with a component, not a permanent database.
14. Best Practices for Passing Data
- Use meaningful keys: Prefer constants over repeatedly typing key strings.
- Validate inputs: Check required values before opening the next activity.
- Handle missing extras: Use nullable retrieval and suitable default values.
- Keep payloads small: Avoid sending large images, lengthy collections, or entire database records through Intent extras.
- Pass identifiers when appropriate: A product ID or user ID can be used to retrieve detailed information from a repository or database.
- Prefer Parcelable for Android objects: Use it when a custom object must be transferred and can be represented appropriately.
- Use the Activity Result API: Prefer it for receiving results from activities.
- Protect sensitive information: Do not put passwords, access tokens, or confidential personal data in an Intent unnecessarily.
- Choose explicit Intents for internal navigation: They clearly identify the destination activity.
- Test edge cases: Try empty inputs, missing values, unexpected data, and repeated navigation.
15. Common Errors and Troubleshooting
| Problem |
Possible Cause |
Solution |
| Received value is null. |
The key is incorrect or the extra was not included. |
Check that both activities use the same key. |
| Integer value is incorrect. |
The retrieval method or default value is inappropriate. |
Use getIntExtra() with the correct key and default. |
| Activity does not open. |
The target activity is missing or the Intent targets the wrong class. |
Check the class name and manifest declaration. |
| App crashes when retrieving an object. |
The object type, retrieval method, or API usage is incorrect. |
Verify the Parcelable or Serializable implementation and Android version. |
| Large data transfer fails. |
The Intent or Binder transaction contains too much data. |
Pass an identifier or URI and load the content separately. |
| Returned value is not displayed. |
The result code or result callback is not handled correctly. |
Check setResult(), RESULT_OK, and the launcher callback. |
| Empty welcome message appears. |
The input is empty or no default message is provided. |
Validate the input and display an appropriate fallback message. |
16. Security Considerations
Intent-based communication must be designed with security in mind, particularly when activities can be reached from outside the application.
- Keep internal activities non-exported unless external applications genuinely need to launch them.
- Validate all values received from external Intents because external callers may provide unexpected or malicious input.
- Avoid exposing private information through exported activities or implicit Intent broadcasts.
- Do not rely on an Intent extra alone to authorize sensitive actions.
- For sensitive operations, validate user permissions and authorization in the appropriate trusted layer.
- Use content URIs and suitable URI permissions for sharing files instead of putting large file contents directly into extras.
17. Practical Exercise
Exercise: Student Profile Application
Create a simple Android application that transfers student information between two activities.
Requirements
- Create a first activity with fields for student name, roll number, and course.
- Add a button labeled View Profile.
- Use an explicit Intent to open the second activity.
- Pass the three values using Intent extras.
- Retrieve the values in the second activity.
- Display the student information in separate TextViews.
- Validate that the name and roll number are not empty.
- Display a suitable message if any required value is missing.
Expected Result
When a user enters the student details and taps View Profile, the second activity should display the submitted name, roll number, and course. If required fields are empty, the application should ask the user to complete them before proceeding.
18. Mini Project: Product Details Navigation
Build a small product browsing application with two activities.
Activity 1: Product List
- Display a list of products.
- Show each product's name and price.
- Allow the user to select a product.
- Pass the selected product ID to the next activity.
Activity 2: Product Details
- Retrieve the product ID from the Intent.
- Load the relevant product details from a repository or local data source.
- Display the product name, price, description, and availability.
- Handle an invalid or missing product ID gracefully.
This project demonstrates a scalable approach because the Intent transfers a small identifier instead of an unnecessarily large data object.
19. Interview Questions and Answers
Q1. What is an Intent in Android?
An Intent is a messaging object that requests an action from an Android component. It can launch activities and carry extra data.
Q2. How can you pass data from one activity to another?
Create an Intent targeting the destination activity, add data with putExtra(), and call startActivity(). The destination retrieves the values from its Intent.
Q3. What is the difference between an explicit and an implicit Intent?
An explicit Intent specifies a particular component. An implicit Intent specifies an action that a compatible component can handle.
Q4. What is the purpose of putExtra()?
putExtra() adds a key-value pair to an Intent so the destination component can retrieve the information.
Q5. How do you retrieve a String extra?
Use intent.getStringExtra("key"). The returned value can be null if the extra is absent.
Q6. How can you pass multiple values?
Add multiple extras using different keys, or group related values in a Bundle.
Q7. What is a Bundle?
A Bundle is a container that stores key-value pairs and supports many common Android data types.
Q8. How can you pass a custom object?
Use a suitable Parcelable or Serializable object and retrieve it with the corresponding API. Parcelable is commonly preferred for Android-specific transfer.
Q9. How do you return data to the previous activity?
Use the Activity Result API to launch the activity and handle its result. The destination can return data through a result Intent and setResult().
Q10. What happens if an Intent extra is missing?
Retrieval methods may return null or a specified default value. The application should handle missing values instead of assuming all extras exist.
Q11. Why should Intent extras be kept small?
Intent data is transferred through Android's component communication mechanisms, which have transaction-size limits. Large payloads can cause failures, so pass an identifier or URI when appropriate.
Q12. Can Intents be used to pass passwords?
Although a String can technically be placed in an Intent, passwords and other sensitive information should not be transferred unnecessarily. Prefer secure authentication flows and avoid exposing confidential data to other components.
20. Quick Revision Notes
- An Activity represents a screen in an Android application.
- An Intent requests an action from an Android component.
- Explicit Intents are useful for navigating to a known activity.
putExtra() attaches data to an Intent.
getStringExtra(), getIntExtra(), and related methods retrieve values.
- A Bundle groups multiple key-value pairs.
- Parcelable is commonly used for custom Android data objects.
- The Activity Result API supports returning data from a launched activity.
- Intent extras are temporary communication data, not persistent storage.
- Always validate incoming data and avoid unnecessarily large or sensitive payloads.
21. Conclusion
Passing data between activities using Intents is a fundamental Android development skill. It allows different screens to communicate and create connected user experiences, from simple welcome screens to product browsing, student profiles, and multi-step forms.
By understanding explicit Intents, Intent extras, Bundles, custom Parcelable objects, and the Activity Result API, developers can implement data transfer effectively. Good validation, small payloads, lifecycle awareness, and security practices help make Android applications reliable and maintainable.
22. Additional Learning Resources
Continue learning Android application development through these JustAcademy resources: